package cn.taketoday.live.http;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;

import org.apache.commons.lang3.StringUtils;
import org.springframework.util.CollectionUtils;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

import cn.taketoday.live.config.GlobalData;
import cn.taketoday.live.data.RoomGift;
import cn.taketoday.live.data.room.CheckTx;
import cn.taketoday.live.data.room.Room;
import cn.taketoday.live.data.room.RoomBlock;
import cn.taketoday.live.data.room.RoomInfo;
import cn.taketoday.live.data.room.RoomInit;
import cn.taketoday.live.data.server.Conf;
import cn.taketoday.live.tools.CurrencyTools;
import cn.taketoday.live.tools.ParseIndentityTools;
import cn.taketoday.live.utils.HttpUtils;
import lombok.extern.slf4j.Slf4j;

/**
 * @author BanqiJane
 * @ClassName HttpRoomData
 * @Description TODO
 * @date 2020年8月10日 下午12:28:59
 * @Copyright:2020 blogs.acproject.xyz Inc. All rights reserved.
 */
@Slf4j
public class HttpRoomData {

  /**
   * 获取连接目标房间websocket端口 接口
   *
   * @return
   */
  public static Conf httpGetConf() {
    String data = null;
    JSONObject jsonObject = null;
    Conf conf = null;
    short code = -1;
    Map<String, String> headers = null;
    Map<String, String> datas = null;
    headers = new HashMap<>(3);
    headers.put("referer", "https://live.bilibili.com/" + CurrencyTools.parseRoomId());
    headers.put("user-agent",
                "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.138 Safari/537.36");
    if (!StringUtils.isEmpty(GlobalData.USERCOOKIE)) {
      headers.put("cookie", GlobalData.USERCOOKIE);
    }
    datas = new HashMap<>(3);
    datas.put("id", GlobalData.ROOM_ID.toString());
    datas.put("type", "0");
    try {
      data = HttpUtils.getString("https://api.live.bilibili.com/xlive/web-room/v1/index/getDanmuInfo", headers, datas);
    }
    catch (Exception e) {
      // TODO 自动生成的 catch 块
      log.error("", e);
      data = null;
    }
    if (data == null)
      return null;
    jsonObject = JSONObject.parseObject(data);
    code = jsonObject.getShort("code");
    if (code == 0) {
      conf = jsonObject.getObject("data", Conf.class);
    }
    else {
      log.error("未知错误,原因:" + jsonObject.getString("message"));
    }
    return conf;
  }

  /**
   * 获取目标房间部分信息
   *
   * @param roomid
   *
   * @return
   */
  public static Room httpGetRoomData(long roomid) {
    String data = null;
    JSONObject jsonObject = null;
    Room room = null;
    short code = -1;
    Map<String, String> headers = null;
    headers = new HashMap<>(3);
    headers.put("referer", "https://live.bilibili.com/" + CurrencyTools.parseRoomId());
    headers.put("user-agent",
                "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.138 Safari/537.36");
//		if (!StringUtils.isEmpty(PublicDataConf.USERCOOKIE)) {
//			headers.put("cookie", PublicDataConf.USERCOOKIE);
//		}
    try {
      data = HttpUtils
              .getString("https://api.live.bilibili.com/room_ex/v1/RoomNews/get?roomid=" + roomid, headers, null);
    }
    catch (Exception e) {
      // TODO 自动生成的 catch 块
      log.error("", e);
      data = null;
    }
    if (data == null)
      return room;
//		LOGGER.debug("获取到的room:" + data);
    jsonObject = JSONObject.parseObject(data);
    code = jsonObject.getShort("code");
    if (code == 0) {
      room = jsonObject.getObject("data", Room.class);
    }
    else {
      log.error("直播房间号不存在，或者未知错误，请尝试更换房间号,原因:" + jsonObject.getString("message"));
    }
    return room;
  }

  /**
   * 获取房间信息
   *
   * @param roomid
   */
  public static RoomInit httpGetRoomInit(long roomid) {
    String data = null;
    short code = -1;
    Map<String, String> headers = new HashMap<>(2);
    headers.put("user-agent",
                "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.138 Safari/537.36");
//		if (!StringUtils.isEmpty(PublicDataConf.USERCOOKIE)) {
//			headers.put("cookie", PublicDataConf.USERCOOKIE);
//		}
    try {
      data = HttpUtils
              .getString("https://api.live.bilibili.com/room/v1/Room/room_init?id=" + roomid, headers, null);
    }
    catch (Exception e) {
      log.error("", e);
      data = null;
    }
    if (data == null)
      return null;
//		LOGGER.debug("获取到的room:" + data);
    JSONObject jsonObject = JSONObject.parseObject(data);
    code = jsonObject.getShort("code");
    RoomInit roomInit = null;
    if (code == 0) {
      roomInit = jsonObject.getObject("data", RoomInit.class);
    }
    else {
      log.error("直播房间号不存在，或者未知错误，请尝试更换房间号,原因: {}", jsonObject.getString("message"));
    }
    return roomInit;
  }

  /**
   * 获取房间最详细信息 日后扩容 目前只是获取主播uid 改
   *
   * @return
   */
  public static RoomInfo httpGetRoomInfo() {
    String data = null;
    JSONObject jsonObject = null;
    RoomInfo roomInfo = null;
    short code = -1;
    Map<String, String> headers = null;
    headers = new HashMap<>(3);
    headers.put("user-agent",
                "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.138 Safari/537.36");
    headers.put("referer", "https://live.bilibili.com/" + CurrencyTools.parseRoomId());
//		if (!StringUtils.isEmpty(PublicDataConf.USERCOOKIE)) {
//			headers.put("cookie", PublicDataConf.USERCOOKIE);
//		}
    try {
      data = HttpUtils
              .getString("https://api.live.bilibili.com/xlive/web-room/v1/index/getInfoByRoom?room_id="
                               + CurrencyTools.parseRoomId(), headers, null)
              ;
    }
    catch (Exception e) {
      // TODO 自动生成的 catch 块
      log.error("", e);
      data = null;
    }
    if (data == null)
      return roomInfo;
//		LOGGER.debug("获取到的room:" + data);
    jsonObject = JSONObject.parseObject(data);
    code = jsonObject.getShort("code");
    if (code == 0) {
      roomInfo = JSON.parseObject(((JSONObject) jsonObject.get("data")).getString("room_info"),
                                  RoomInfo.class);
    }
    else {
      log.error("获取房间详细信息失败，请稍后尝试:" + jsonObject.getString("message"));
    }
    return roomInfo;
  }

  /**
   * 获取关注名字集合
   *
   * @return 关注uname集
   */
  public static ConcurrentHashMap<Long, String> httpGetFollowers() {
    String data = null;
    JSONObject jsonObject = null;
    Integer page = null;
    JSONArray jsonArray = null;
    short code = -1;
    ConcurrentHashMap<Long, String> followConcurrentHashMap = null;
    Map<String, String> headers = null;
    Map<String, String> datas = null;
    if (GlobalData.AU_ID == null) {
      return null;
    }
    if (GlobalData.FAN_SNUM.equals(null) || GlobalData.FAN_SNUM.equals(0L)) {
      page = 1;
    }
    else {
      page = (int) Math.ceil((float) GlobalData.FAN_SNUM / 20F);
      page = page > 5 ? 5 : page;
    }
    followConcurrentHashMap = new ConcurrentHashMap<Long, String>();
    while (page > 0) {
      headers = new HashMap<>(3);
      headers.put("referer", "https://space.bilibili.com/{" + GlobalData.AU_ID + "}/");
      headers.put("user-agent",
                  "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.138 Safari/537.36");
//			if (!StringUtils.isEmpty(PublicDataConf.USERCOOKIE)) {
//				headers.put("cookie", PublicDataConf.USERCOOKIE);
//			}
      datas = new HashMap<>(6);
      datas.put("vmid", GlobalData.AU_ID.toString());
      datas.put("pn", String.valueOf(page));
      datas.put("ps", "50");
      datas.put("order", "desc");
      datas.put("jsonp", "jsonp");
      try {
        data = HttpUtils
                .getString("https://api.bilibili.com/x/relation/followers", headers, datas);
      }
      catch (Exception e) {
        // TODO 自动生成的 catch 块
        log.error("", e);
        data = null;
      }
      if (data == null)
        return null;
      jsonObject = JSONObject.parseObject(data);
      try {
        code = jsonObject.getShort("code");
      }
      catch (Exception e) {
        // TODO: handle exception
        log.error("获取关注错误");
        return followConcurrentHashMap;
      }

      if (code == 0) {
        GlobalData.FAN_SNUM = ((JSONObject) jsonObject.get("data")).getLong("total");
        jsonArray = ((JSONObject) jsonObject.get("data")).getJSONArray("list");
        for (Object object : jsonArray) {
          followConcurrentHashMap.put(((JSONObject) object).getLong("mid"),
                                      ((JSONObject) object).getString("uname"));
        }
      }
      else {
        log.error("获取关注数失败，请重试" + jsonObject.getString("message"));
      }
      page--;
    }
    return followConcurrentHashMap;
  }

  /**
   * 获取关注数
   *
   * @return 返回关注数
   */
  public static Long httpGetFollowersNum() {
    String data = null;
    JSONObject jsonObject = null;
    short code = -1;
    Map<String, String> headers = null;
    Map<String, String> datas = null;
    Long followersNum = 0L;
    if (GlobalData.AU_ID == null) {
      return followersNum;
    }
    headers = new HashMap<>(3);
    headers.put("referer", "https://space.bilibili.com/{" + GlobalData.AU_ID + "}/");
    headers.put("user-agent",
                "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.138 Safari/537.36");
//			if (!StringUtils.isEmpty(PublicDataConf.USERCOOKIE)) {
//				headers.put("cookie", PublicDataConf.USERCOOKIE);
//			}
    datas = new HashMap<>(6);
    datas.put("vmid", GlobalData.AU_ID.toString());
    datas.put("pn", String.valueOf(1));
    datas.put("ps", "50");
    datas.put("order", "desc");
    datas.put("jsonp", "jsonp");
    try {
      data = HttpUtils.getString("https://api.bilibili.com/x/relation/followers", headers, datas)
              ;
    }
    catch (Exception e) {
      // TODO 自动生成的 catch 块
      log.error("", e);
      data = null;
    }
    if (data == null)
      return followersNum;
    jsonObject = JSONObject.parseObject(data);
    code = jsonObject.getShort("code");
    if (code == 0) {
      followersNum = ((JSONObject) jsonObject.get("data")).getLong("total");
    }
    else {
      log.error("获取关注数失败，请重试" + jsonObject.getString("message"));
    }
    return followersNum;
  }

  public static Hashtable<Long, String> httpGetGuardList() {
    String data = null;
    Hashtable<Long, String> hashtable = new Hashtable<Long, String>();
    JSONObject jsonObject = null;
    JSONArray jsonArray = null;
    Map<String, String> headers = null;
    Map<String, String> datas = null;
    short code = -1;
    int totalSize = httpGetGuardListTotalSize();
    int page = 0;
    if (totalSize == 0) {
      return null;
    }
    page = (int) Math.ceil((float) totalSize / 29F);
    if (page == 0) {
      page = 1;
    }
    for (int i = 1; i <= page; i++) {
      headers = new HashMap<>(3);
      headers.put("referer", "https://live.bilibili.com/" + CurrencyTools.parseRoomId());
      headers.put("user-agent",
                  "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.138 Safari/537.36");
//			if (!StringUtils.isEmpty(PublicDataConf.USERCOOKIE)) {
//				headers.put("cookie", PublicDataConf.USERCOOKIE);
//			}
      datas = new HashMap<>(4);
      datas.put("roomid", GlobalData.ROOM_ID.toString());
      datas.put("page", String.valueOf(i));
      datas.put("ruid", GlobalData.AU_ID.toString());
      datas.put("page_size", "29");
      try {
        data = HttpUtils
                .getString("https://api.live.bilibili.com/xlive/app-room/v1/guardTab/topList", headers, datas)
                ;
      }
      catch (Exception e) {
        // TODO 自动生成的 catch 块
        log.error("", e);
        data = null;
      }
      if (data == null)
        return null;
      jsonObject = JSONObject.parseObject(data);
      code = jsonObject.getShort("code");
      if (code == 0) {
        jsonArray = ((JSONObject) jsonObject.get("data")).getJSONArray("list");
        for (Object object : jsonArray) {
          try {
            Thread.sleep(1);
          }
          catch (InterruptedException e) {
            e.printStackTrace();
          }
          hashtable.put(((JSONObject) object).getLong("uid"), ((JSONObject) object).getString("username"));
        }
        if (i == 1) {
          jsonArray = ((JSONObject) jsonObject.get("data")).getJSONArray("top3");
          for (Object object : jsonArray) {
            hashtable.put(((JSONObject) object).getLong("uid"),
                          ((JSONObject) object).getString("username"));
          }
        }
      }
      else {
        log.error("直播房间号不存在，或者未知错误，请尝试更换房间号,原因:" + jsonObject.getString("message"));
      }
    }
    return hashtable;
  }

  public static int httpGetGuardListTotalSize() {
    String data = null;
    Map<String, String> headers = null;
    Map<String, String> datas = null;
    int num = 0;
    JSONObject jsonObject = null;
    short code = -1;
    headers = new HashMap<>(3);
    headers.put("referer", "https://live.bilibili.com/" + CurrencyTools.parseRoomId());
    headers.put("user-agent",
                "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.138 Safari/537.36");
//		if (!StringUtils.isEmpty(PublicDataConf.USERCOOKIE)) {
//			headers.put("cookie", PublicDataConf.USERCOOKIE);
//		}
    datas = new HashMap<>(5);
    datas.put("roomid", GlobalData.ROOM_ID.toString());
    datas.put("page", String.valueOf(1));
    datas.put("ruid", GlobalData.AU_ID.toString());
    datas.put("page_size", "29");
    try {
      data = HttpUtils
              .getString("https://api.live.bilibili.com/xlive/app-room/v1/guardTab/topList", headers, datas)
              ;
    }
    catch (Exception e) {
      // TODO 自动生成的 catch 块
      log.error("", e);
      data = null;
    }
    if (data == null)
      return num;
    jsonObject = JSONObject.parseObject(data);
    code = jsonObject.getShort("code");
    if (code == 0) {
      num = ((JSONObject) ((JSONObject) jsonObject.get("data")).get("info")).getInteger("num");
    }
    else {
      log.error("直播房间号不存在，或者未知错误，请尝试更换房间号,原因:" + jsonObject.getString("message"));
    }
    return num;
  }

  public static CheckTx httpGetCheckTX() {
    String data = null;
    JSONObject jsonObject = null;
    short code = -1;
    Map<String, String> headers = null;
    headers = new HashMap<>(3);
    headers.put("user-agent",
                "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.138 Safari/537.36");
    headers.put("referer", "https://live.bilibili.com/" + CurrencyTools.parseRoomId());
//		if (!StringUtils.isEmpty(PublicDataConf.USERCOOKIE)) {
//			headers.put("cookie", PublicDataConf.USERCOOKIE);
//		}
    try {
      data = HttpUtils
              .getString("https://api.live.bilibili.com/xlive/lottery-interface/v1/Anchor/Check?roomid="
                               + CurrencyTools.parseRoomId(), headers, null)
              ;
    }
    catch (Exception e) {
      // TODO 自动生成的 catch 块
      log.error("", e);
      data = null;
    }
    if (data == null)
      return null;
    jsonObject = JSONObject.parseObject(data);
    code = jsonObject.getShort("code");
    if (code == 0) {
      if (jsonObject.get("data") != null) {
        return new CheckTx(((JSONObject) jsonObject.get("data")).getLong("room_id"),
                           ((JSONObject) jsonObject.get("data")).getString("gift_name"),
                           ((JSONObject) jsonObject.get("data")).getShort("time"));
      }
    }
    else {
      log.error("检查天选礼物失败,原因:" + jsonObject.getString("message"));
    }
    return null;
  }

  public static void httpGetRoomGifts() {
    String data = null;
    JSONObject jsonObject = null;
    JSONArray jsonArray = null;
    short code = -1;
    Map<String, String> headers = null;
    headers = new HashMap<>(3);
    headers.put("user-agent",
                "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.138 Safari/537.36");
    headers.put("referer", "https://live.bilibili.com/" + CurrencyTools.parseRoomId());
    try {
      data = HttpUtils
              .getString("https://api.live.bilibili.com/xlive/web-room/v1/giftPanel/giftConfig?platform=pc&room_id="
                               + CurrencyTools.parseRoomId(), headers, null)
              ;
    }
    catch (Exception e) {
      // TODO 自动生成的 catch 块
      log.error("", e);
      data = null;
    }
    if (data == null)
      return;
    jsonObject = JSONObject.parseObject(data);
    code = jsonObject.getShort("code");
    if (code == 0) {
      jsonArray = ((JSONObject) jsonObject.get("data")).getJSONArray("list");
      if (GlobalData.roomGiftConcurrentHashMap.size() < 1) {
        for (Object object : jsonArray) {
          GlobalData.roomGiftConcurrentHashMap.put(((JSONObject) object).getInteger("id"),
                                                   new RoomGift(((JSONObject) object).getInteger("id"),
                                                                    ((JSONObject) object).getString("name"), ParseIndentityTools
                                                                            .parseCoin_type(((JSONObject) object).getString("coin_type")),
                                                                    ((JSONObject) object).getString("webp")));
        }
      }
    }
    else {
      log.error("获取礼物失败,原因:" + jsonObject.getString("message"));
    }
  }

  public static List<RoomBlock> getBlockList(int page) {
    String data = null;
    JSONObject jsonObject = null;
    JSONArray jsonArray = null;
    List<RoomBlock> roomBlocks = new ArrayList<>();
    Map<String, String> headers = null;
    Map<String, String> datas = null;
    headers = new HashMap<>(4);
    datas = new HashMap<>(4);
    headers.put("user-agent",
                "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.138 Safari/537.36");
    headers.put("referer", "https://live.bilibili.com/" + CurrencyTools.parseRoomId());
    if (!StringUtils.isEmpty(GlobalData.USERCOOKIE)) {
      headers.put("cookie", GlobalData.USERCOOKIE);
    }
    datas.put("roomid", String.valueOf(GlobalData.ROOM_ID));
    datas.put("page", String.valueOf(page));
    try {
      data = HttpUtils
              .getString("https://api.live.bilibili.com/liveact/ajaxGetBlockList", headers, datas)
              ;
    }
    catch (Exception e) {
      // TODO 自动生成的 catch 块
      log.error("", e);
      data = null;
    }
    if (data == null)
      return roomBlocks;
    jsonObject = JSONObject.parseObject(data);
    short code = jsonObject.getShort("code");
    if (code == 0) {
      jsonArray = jsonObject.getJSONArray("data");
      if (!CollectionUtils.isEmpty(jsonArray)) {
        roomBlocks = new ArrayList<>(jsonArray.toJavaList(RoomBlock.class));
      }
      return roomBlocks;
    }
    return roomBlocks;
  }
}
